package com.service.weChatWifiLogin.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.service.config.utils.*;
import com.service.weChatWifiLogin.dao.CustomerOrBossDao;
import com.service.weChatWifiLogin.dao.ShopCustomerDao;
import com.service.weChatWifiLogin.dao.ShopInfoDao;
import com.service.weChatWifiLogin.dto.*;
import com.service.weChatWifiLogin.entity.*;
import com.service.weChatWifiLogin.service.*;
import com.service.weChatWifiLogin.utile.AESCBCUtil;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.service.config.constant.ApiUrlConstants.*;
import static com.service.config.constant.Constant.USER_NOT_FOUND;

/**
 * 店铺顾客表(ShopCustomer)表服务实现类
 *
 * @author makejava
 * @since 2021-06-16 17:10:39
 */
@Service("shopCustomerService")
public class ShopCustomerServiceImpl implements ShopCustomerService {
    @Resource
    private ShopCustomerDao shopCustomerDao;

    @Resource
    private ShopInfoDao shopInfoDao;
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private CustomerOrBossDao customerOrBossDao;

    @Resource
    private CustomerOrBossService customerOrBossService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private VFilePhysicsInfoService vFilePhysicsInfoService;
    @Resource
    QueryWeiChatServiceImpl queryWeiChatService;
    @Resource
    private ConnectSuccessInfoService connectSuccessInfoService;
    @Resource
    private ConnectErrorInfoService connectErrorInfoService;

    /**
     * 通过ID查询单条数据
     *
     * @param customerOrBossId 主键
     * @return 实例对象
     */
    @Override
    public ShopCustomer queryById(String customerOrBossId) {
        return this.shopCustomerDao.queryById(customerOrBossId);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<ShopCustomer> queryAllByLimit(int offset, int limit) {
        return this.shopCustomerDao.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param shopCustomer 实例对象
     * @return 实例对象
     */
    @Override
    public ShopCustomer insert(ShopCustomer shopCustomer) {
        this.shopCustomerDao.insert(shopCustomer);
        return shopCustomer;
    }

    /**
     * 修改数据
     *
     * @param shopCustomer 实例对象
     * @return 实例对象
     */
    @Override
    public ShopCustomer update(ShopCustomer shopCustomer) {
        this.shopCustomerDao.update(shopCustomer);
        return this.queryById(shopCustomer.getCustomerOrBossId());
    }

    /**
     * 通过主键删除数据
     *
     * @param customerOrBossId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(String customerOrBossId) {
        return this.shopCustomerDao.deleteById(customerOrBossId) > 0;
    }

    /**
     * 查询ssid列表对应的店铺信息
     *
     * @param ssidDtos
     * @return
     */
    @Override
    public List<ShopDto> queryShopsBySsids(List<SsIdName> ssidDtos) {
        List<ShopInfo> shopInfos = new ArrayList<>();
        List<ShopInfo> shopInfoList1 = shopInfoDao.queryAll(new ShopInfo());
        List<ShopInfo> collect1 = shopInfoList1.stream().filter(shopInfo -> shopInfo.getSsidName() != null && !"".equals(shopInfo.getSsidName()) &&
                shopInfo.getSsidFlag() != null && !"".equals(shopInfo.getSsidFlag())).collect(Collectors.toList());
        if (collect1.size() > 0) {
            List<ShopInfo> finalShopInfos = shopInfos;
            collect1.stream().forEach(shopInfo -> {
                ssidDtos.stream().forEach(ssIdName -> {
                    if (ssIdName.getSSID() != null && !"".equals(ssIdName.getSSID())) {
                        if (ssIdName.getSSID().equals(shopInfo.getSsidFlag()+"_"+shopInfo.getSsidName())) {
                            finalShopInfos.add(shopInfo) ;
                        }
                    }
                });
            });
            List<ShopInfo> collect = finalShopInfos.stream().distinct().collect(Collectors.toList());
            if (collect.size() > 0) {
                shopInfos = collect.stream().filter(s -> !s.getStatus()).collect(Collectors.toList());
                shopInfos.stream().forEach(shopInfo -> {
                    if (shopInfo.getLogoType() != null && !shopInfo.getLogoType().equals("")) {
                        if (shopInfo.getLogoType()==0) {
                            // 设置logo的url
                            VFilePhysicsInfo vFilePhysicsInfo = vFilePhysicsInfoService.queryById(shopInfo.getLogoId());
                            if (vFilePhysicsInfo != null) {
                                shopInfo.setLogoId(vFilePhysicsInfo.getFileseverdomain()+vFilePhysicsInfo.getFiledicdomain()
                                        +"/"+vFilePhysicsInfo.getFilename());
                            }
                        }
                    }
                    if (shopInfo.getMarketingType()!=null && !"".equals(shopInfo.getMarketingType())) {
                        if (shopInfo.getMarketingType()==0) { // 设置营销图片的url
                            VFilePhysicsInfo vFilePhysicsInfo = vFilePhysicsInfoService.queryById(shopInfo.getMarketingId());
                            if (vFilePhysicsInfo != null) {
                                shopInfo.setMarketingId(vFilePhysicsInfo.getFileseverdomain()+vFilePhysicsInfo.getFiledicdomain()
                                        +"/"+vFilePhysicsInfo.getFilename());
                            }
                        }
                    }
                });
                List<ShopDto> shopDtos = ModelMapperUtil.strictMapList(shopInfos, ShopDto.class);
                return shopDtos;
            }
        }
        List<ShopInfo> shopInfos1 = new ArrayList<>();
        return  ModelMapperUtil.strictMapList(shopInfos1, ShopDto.class);
    }

    /**
     * 获取客户信息并保存
     *
     * @param
     */
    @Override
    @Transactional
    public Result queryAuthorized(CustomerRegisterDto customerRegisterDto,String bAuthToken) throws Exception {
        if (redisUtil.exist(bAuthToken)) {
            CustomerOrBoss customerOrBoss =  JsonXMLUtils.json2obj(redisUtil.getValue(bAuthToken), CustomerOrBoss.class);
            customerOrBoss = customerOrBossDao.queryById(customerOrBoss.getId());
            if (customerRegisterDto.getIv()!=null && !"".equals(customerRegisterDto.getIv()) &&
                    customerRegisterDto.getEncryptedData()!=null && !"".equals(customerRegisterDto.getEncryptedData())) {
               HashMap openId = queryWeiChatService.getOpenId(queryWeiChatService.getUrl( customerRegisterDto.getCode(), "", CUSTOMER_APP_ID, CUSTOMER_SECRET));
                if (openId.containsKey("errcode")) {
                    return Result.ok().setData(openId);
                }
                Map<String, Object> map2 = JsonXMLUtils.json2map(openId.get("weiChatDto").toString());
                WeiChatDto weiChatDto = ModelMapperUtil.strictMap(map2, WeiChatDto.class);
                String decrypt = AESCBCUtil.decrypt(customerRegisterDto.getEncryptedData(), weiChatDto.getSession_key(), customerRegisterDto.getIv(), "UTF-8");
                WeiChatPhoneNumberDto weiChatPhoneNumberDto = JsonXMLUtils.json2obj(decrypt, WeiChatPhoneNumberDto.class);
                if (weiChatPhoneNumberDto != null) {
                    if (weiChatPhoneNumberDto.getPhoneNumber() != null) {
                        customerOrBoss.setTelphone(weiChatPhoneNumberDto.getPhoneNumber());
                    }
                    if (weiChatPhoneNumberDto.getPurePhoneNumber() != null) {
                        customerOrBoss.setTelphone(weiChatPhoneNumberDto.getPurePhoneNumber());
                    }
                }
                customerOrBossDao.update(customerOrBoss);
                redisUtil.set(bAuthToken,5,JsonXMLUtils.obj2json(customerOrBoss),30); // 更新缓存
                return Result.ok();
            }else {
                if (customerOrBoss.getSuccesCount() != null) {
                    customerOrBoss.setSuccesCount(customerOrBoss.getSuccesCount()+1);
                }else {
                    customerOrBoss.setSuccesCount(1);
                }
                getTelphone(customerRegisterDto, customerOrBoss,bAuthToken);
                return Result.ok();
            }
        }else { // 缓存不存在 与微信交互
            HashMap openId = queryWeiChatService.getOpenId(queryWeiChatService.getUrl(customerRegisterDto.getCode(), "", CUSTOMER_APP_ID, CUSTOMER_SECRET)); // 微信交互
            if (openId.containsKey("errcode")) {
                return Result.ok().setData(openId);
            }
            Map<String, Object> map2 = JsonXMLUtils.json2map(openId.get("weiChatDto").toString());
            WeiChatDto weiChatDto = ModelMapperUtil.strictMap(map2, WeiChatDto.class);
            CustomerOrBoss customerOrBoss = customerOrBossDao.queryByOpenId(weiChatDto.getOpenid());
            customerOrBoss.setOpenId(weiChatDto.getOpenid());
            customerOrBoss.setSessionKey(weiChatDto.getSession_key());
            customerOrBoss.setAddtime(new Date());
            customerOrBoss.setUpdatetime(new Date());
            // 解密手机号
            if (customerRegisterDto.getIv() != null && !"".equals(customerRegisterDto.getIv()) &&
                    customerRegisterDto.getEncryptedData() != null && !"".equals(customerRegisterDto.getEncryptedData())) {
                // 工具类解密
                String s = com.service.weChatWifiLogin.utile.AESCBCUtil.decrypt(customerRegisterDto.getEncryptedData(),weiChatDto.getSession_key(), customerRegisterDto.getIv(),"utf-8");
                WeiChatPhoneNumberDto weiChatPhoneNumberDto = ModelMapperUtil.strictMap(s, WeiChatPhoneNumberDto.class);
                customerOrBoss.setTelphone(weiChatPhoneNumberDto.getPhoneNumber());
                customerOrBossDao.update(customerOrBoss);
                redisUtil.set(bAuthToken,5,JsonXMLUtils.obj2json(customerOrBoss),30); // 更新缓存
                return Result.ok();
            }
            if (customerOrBoss.getSuccesCount() != null) {
                customerOrBoss.setSuccesCount(customerOrBoss.getSuccesCount()+1);
            }else {
                customerOrBoss.setSuccesCount(1);
            }
            getTelphone(customerRegisterDto, customerOrBoss,bAuthToken);
            return Result.ok();
        }
    }

    @Override
    public Result queryPhone(String code, String bAuthToken) throws Exception {
        if (redisUtil.exist(bAuthToken)) {
            CustomerOrBoss customerOrBoss =  JsonXMLUtils.json2obj(redisUtil.getValue(bAuthToken), CustomerOrBoss.class);
            if (customerOrBoss.getTelphone() == null || customerOrBoss.getTelphone().equals("")) {
                HashMap map = new HashMap();
                map.put("errorMsg","手机号未授权");
                map.put("code",USER_NOT_FOUND);
                return Result.ok().setData(map);
            }else {
                return Result.ok();
            }
        }else {
            HashMap openId = queryWeiChatService.getOpenId(queryWeiChatService.getUrl(code, "", CUSTOMER_APP_ID, CUSTOMER_SECRET));
            if (openId.containsKey("errcode")) {
                return Result.ok().setData(openId);
            }
            Map<String, Object> map2 = JsonXMLUtils.json2map(openId.get("weiChatDto").toString());
            WeiChatDto weiChatDto = ModelMapperUtil.strictMap(map2, WeiChatDto.class);
            CustomerOrBoss customerOrBoss = customerOrBossDao.queryByOpenId(weiChatDto.getOpenid());
            if (customerOrBoss.getTelphone() == null || customerOrBoss.getTelphone().equals("")) {
                HashMap map = new HashMap();
                map.put("errorMsg","手机号未授权");
                map.put("code",USER_NOT_FOUND);
                return Result.ok().setData(map);
            }else {
                return Result.ok();
            }
        }
    }

    /**
     * 新增连接失败信息
     * @param connectErrorInfoDto
     * @param bAuthToken
     * @return
     */
    @Override
    public Result addConnectErrorInfo(ConnectErrorInfoDto connectErrorInfoDto, String bAuthToken) throws Exception {
        if (redisUtil.exist(bAuthToken)) {
            CustomerOrBoss customerOrBoss =  JsonXMLUtils.json2obj(redisUtil.getValue(bAuthToken), CustomerOrBoss.class);
            ConnectErrorInfo connectErrorInfo = ModelMapperUtil.strictMap(connectErrorInfoDto, ConnectErrorInfo.class);
            if (connectErrorInfo.getReason() == null || "".equals(connectErrorInfo.getReason() == null)) {
                connectErrorInfo.setReason("未知错误");
            }
            connectErrorInfo.setId(IdUtil.getStringId());
            connectErrorInfo.setDate(new Date());
            connectErrorInfo.setTransactionalId(customerOrBoss.getTransactionalId());
            connectErrorInfo = connectErrorInfoService.insertInfo(connectErrorInfo);
            if (connectErrorInfo != null) {
                return Result.ok();
            }
        }
        return Result.ok();
    }

    /**
     * 更新数据

     * @param customerOrBoss
     */
    private void getTelphone(CustomerRegisterDto customerRegisterDto ,CustomerOrBoss customerOrBoss,String bAuthToken) throws Exception {
        if (customerRegisterDto.getNickName() != null && !customerRegisterDto.getNickName().equals("")) {
            customerOrBoss.setNickName(customerRegisterDto.getNickName());
        }
        customerOrBoss.setUpdatetime(new Date());
        customerOrBossService.update(customerOrBoss);// 更新成功次数
        redisUtil.set(bAuthToken,5,JsonXMLUtils.obj2json(customerOrBoss),30); // 更新缓存
        ShopCustomer shopCustomer = shopCustomerDao.queryAuthorized(customerOrBoss.getId(),customerRegisterDto.getShopId()); // 该店铺下是否存在该用户
        if(shopCustomer == null){ //该店铺下不存在该用户
            addShopCustomer(customerRegisterDto.getShopId(),customerOrBoss.getId()); // 该店铺下新增用户
            connectSuccessInfoService.insertRecords(customerOrBoss.getTransactionalId(),customerRegisterDto.getShopId());// 增加联网成功记录
        }else {//该店铺下存在该用户
            shopCustomer.setSuccessCount(shopCustomer.getSuccessCount()+1);
            shopCustomer.setScanCount(shopCustomer.getScanCount()+1);
            shopCustomerDao.update(shopCustomer);
            connectSuccessInfoService.insertRecords(customerOrBoss.getTransactionalId(),customerRegisterDto.getShopId());// 增加联网成功记录
        }
    }

    /***
     * 新增店铺顾客记录
     * @param shopId
     * @param id
     * @return
     */
    private ShopCustomer addShopCustomer(String shopId, String id) {
        ShopCustomer shopCustomer = new ShopCustomer();
        shopCustomer.setShopId(shopId);
        shopCustomer.setCustomerOrBossId(id);
        shopCustomer.setScanCount(1);
        shopCustomer.setSuccessCount(1);
        shopCustomerDao.insert(shopCustomer);
        return shopCustomer;
    }
}
